/**
 * hello
 * 反射
 */
public class hello {

    public static void main(String[] args) {

        Class cls1 = String.class;
        System.out.println(cls1);

        String s = "hello";
        Class cls2 = s.getClass();
        System.out.println(cls2);


        printClassInfo("".getClass());

        creatInstance();

    }

    private static void printClassInfo(Class cls){
        //因为反射的目的是为了获得某个实例的信息。因此，当我们拿到某个Object实例时，我们可以通过反射获取该Object的class信息：
        System.out.println("Class name: " + cls.getName());
        System.out.println("Simple name: " + cls.getSimpleName());
        if (cls.getPackage() != null) {
            System.out.println("Package name: " + cls.getPackage().getName());
        }
        System.out.println("is interface: " + cls.isInterface());
        System.out.println("is enum: " + cls.isEnum());
        System.out.println("is array: " + cls.isArray());
        System.out.println("is primitive: " + cls.isPrimitive());
    }

    // 如果获取到了一个Class实例，我们就可以通过该Class实例来创建对应类型的实例
    private static void creatInstance(){
        // 获取String的Class实例:
        // Class cls = String.class;
        // 创建一个String实例
        // String s = (String) cls.newInstance(); //这个方法在jdk9中被废弃
        // s = "hello";
        // System.out.println(s);
        // 上述代码相当于new String()。通过Class.newInstance()可以创建类实例，它的局限是：只能调用public的无参数构造方法。带参数的构造方法，或者非public的构造方法都无法通过Class.newInstance()被调用。
    }
    // 动态加载
    // JVM在执行Java程序的时候，并不是一次性把所有用到的class全部加载到内存，而是第一次需要用到class时才加载.
    // 动态加载class的特性对于Java程序非常重要。利用JVM动态加载class的特性，我们才能在运行期根据条件加载不同的实现类。例如，Commons Logging总是优先使用Log4j，只有当Log4j不存在时，才使用JDK的logging



}